import { _decorator, Color, Component, game, Graphics, Node, view } from 'cc';
const { ccclass, property } = _decorator;

enum FADE_STATE_ENUM {
    IDLE = 'IDLE',
    FADE_IN = 'FADE_IN',
    FADE_OUT = 'FADE_OUT',
}

export const DEFAULT_DURATION = 200;

@ccclass('DrawManager')
export class DrawManager extends Component {
    private ctx: Graphics;
    private state: FADE_STATE_ENUM = FADE_STATE_ENUM.IDLE;

    private oldTime: number;
    private duration: number = DEFAULT_DURATION;

    private fadeResolve: (value: PromiseLike<null>) => void;

    init() {
        this.ctx = this.addComponent(Graphics);
        this.setAlpha(1);
    }

    setAlpha(opacity: number) {
        this.ctx.clear();
        this.ctx.rect(0, 0, view.getVisibleSize().width, view.getViewportRect().height);
        this.ctx.fillColor = new Color(0, 0, 0, opacity * 255);
        this.ctx.fill();
    }

    protected update(dt: number): void {
        switch (this.state) {
            case FADE_STATE_ENUM.FADE_IN: {
                const percent = (game.totalTime - this.oldTime) / this.duration;
                if (percent < 1) {
                    this.setAlpha(percent);
                } else {
                    this.setAlpha(1);
                    this.state = FADE_STATE_ENUM.IDLE;
                    this.fadeResolve(null);
                }
                break;
            }
            case FADE_STATE_ENUM.FADE_OUT: {
                const percent = (game.totalTime - this.oldTime) / this.duration;
                if (percent < 1) {
                    this.setAlpha(1 - percent);
                } else {
                    this.setAlpha(0);
                    this.state = FADE_STATE_ENUM.IDLE;
                    this.fadeResolve(null);
                }
                break;
            }
        }
    }

    fadeIn(duration: number = DEFAULT_DURATION) {
        this.setAlpha(0);
        this.duration = duration;
        this.oldTime = game.totalTime;
        this.state = FADE_STATE_ENUM.FADE_IN;
        return new Promise(resolve => {
            this.fadeResolve = resolve;
        });
    }

    fadeOut(duration: number = DEFAULT_DURATION) {
        this.setAlpha(1);
        this.duration = duration;
        this.oldTime = game.totalTime;
        this.state = FADE_STATE_ENUM.FADE_OUT;
        return new Promise(resolve => {
            this.fadeResolve = resolve;
        });
    }

    mask() {
        this.setAlpha(1);
        this.state = FADE_STATE_ENUM.IDLE;
        return new Promise((resolve) => {
            setTimeout(resolve, DEFAULT_DURATION);
        });
    }
}

